package io.adrainty.demo.seata.account.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.adrainty.demo.seata.account.mapper.AccountMapper;
import io.adrainty.demo.seata.account.models.bo.AccountBO;
import io.adrainty.demo.seata.account.models.entity.AccountEntity;
import io.adrainty.demo.seata.account.service.IAccountService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * <p>AccountServiceImpl</p>
 *
 * @author AdRainty
 * @version V1.0.0
 * @description AccountServiceImpl
 * @since 2025/8/20 13:42:24
 */

@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, AccountBO> implements IAccountService {

    @Override
    public Boolean addAccountBalance(AccountEntity param) {
        Wrapper<AccountBO> updateWrapper = Wrappers.lambdaUpdate(AccountBO.class)
                .eq(AccountBO::getAccountNo, param.getAccountNo())
                .setSql("frozen_balance = frozen_balance - {0}", param.getAccountBalance());
        return this.update(updateWrapper);
    }

    @Override
    public Boolean frozenBalance(AccountEntity param) {
        AccountBO accountBO = this.lambdaQuery()
                .eq(AccountBO::getAccountNo, param.getAccountNo())
                .one();
        if (accountBO == null) {
            throw new RuntimeException("账户不存在");
        }
        BigDecimal currentAccountBalance = accountBO.getAccountBalance();
        BigDecimal remainBalance = currentAccountBalance.subtract(param.getAccountBalance());
        if (remainBalance.compareTo(BigDecimal.ZERO) < 0) {
            throw new RuntimeException("账户余额不足");
        }

        Wrapper<AccountBO> updateWrapper = Wrappers.lambdaUpdate(AccountBO.class)
                .eq(AccountBO::getAccountNo, param.getAccountNo())
                .eq(AccountBO::getAccountBalance, currentAccountBalance)
                .setSql("account_balance = account_balance - {0}", param.getAccountBalance())
                .setSql("frozen_balance = frozen_balance + {0}", param.getAccountBalance());
        return this.update(updateWrapper);
    }

    @Override
    public Boolean rollBackAccountBalance(AccountEntity accountEntity) {
        Wrapper<AccountBO> updateWrapper = Wrappers.lambdaUpdate(AccountBO.class)
                .eq(AccountBO::getAccountNo, accountEntity.getAccountNo())
                .setSql("account_balance = account_balance + {0}", accountEntity.getAccountBalance())
                .setSql("frozen_balance = frozen_balance - {0}", accountEntity.getAccountBalance());
        return this.update(updateWrapper);
    }

}
